package org.jeecg.config;

import com.github.shyiko.mysql.binlog.BinaryLogClient;
import com.github.shyiko.mysql.binlog.event.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * @author gbstart
 * @create 2024-06-03 11:01
 */
//@Component
@Slf4j  //用于打印日志
//在SpringBoot中，提供了一个接口：ApplicationRunner。
//该接口中，只有一个run方法，他执行的时机是：spring容器启动完成之后，就会紧接着执行这个接口
public class MysqlBinLogClient implements ApplicationRunner {


    private Map<String, Map<String, String>> dbTableCols;

    private Map<Long, String> dbTableIdCols = new HashMap<>();


    @Override
    public void run(ApplicationArguments args) throws Exception {
        //项目启动完成连接bin-log
//         new Thread(() -> {
//            connectMysqlBinLog();
//        }).start();
    }

    /**
     * 连接mysqlBinLog
     */
    public void connectMysqlBinLog() {
        log.info("监控BinLog服务已启动");
        //自己MySQL的信息。host，port，username，password
        BinaryLogClient client = new BinaryLogClient("jlmingjun.mysql.polardb.rds.aliyuncs.com", 3306, "jlmj", "Lxkj888!");
        /**因为binlog不是以数据库为单位划分的，所以监控binglog不是监控的单个的数据库，而是整个当前所设置连接的MySQL，
         *其中任何一个库发生数据增删改，这里都能检测到，
         *所以不用设置所监控的数据库的名字(我也不知道怎么设置，没发现有包含这个形参的构造函数)
         *如果需要只监控指定的数据库，可以看后面代码，可以获取到当前发生变更的数据库名称。可以根据名称来决定是否监控
         **/

        client.setServerId(100); //和自己之前设置的server-id保持一致，但是我不知道为什么不一致也能成功

        //下面直接照抄就行
        client.registerEventListener(event -> {
            boolean isjk = true;
            EventData data = event.getData();
            String database = "";
            String table = "";
            long tableId = 0L;
            if (data instanceof TableMapEventData) {
                //只要连接的MySQL发生的增删改的操作，则都会进入这里，无论哪个数据库
                TableMapEventData tableMapEventData = (TableMapEventData) data;
                //可以通过转成TableMapEventData类实例的tableMapEventData来获取当前发生变更的数据库
                database = tableMapEventData.getDatabase();
                //表ID
                tableId = tableMapEventData.getTableId();
                //表名字
                table = tableMapEventData.getTable();
//                System.out.println(tableMapEventData.getTable());
                if(database.equals("tsl_db")){
//                    System.out.println(database+" "+tableId+" "+table);
                    dbTableIdCols.put(tableId,table);
                }
            }

            //表数据发生修改时触发
            if (data instanceof UpdateRowsEventData) {
                UpdateRowsEventData updateRowsEventData  = (UpdateRowsEventData) data;
                long tableId1 = updateRowsEventData.getTableId();
                if(dbTableIdCols.containsKey(tableId1)){
//                    try {
//                        changeDataAutoRecord.update( updateRowsEventData,dbTableIdCols.get(tableId1));
//                    } catch (ClassNotFoundException e) {
//                        throw new RuntimeException(e);
//                    } catch (IllegalAccessException e) {
//                        throw new RuntimeException(e);
//                    } catch (InstantiationException e) {
//                        throw new RuntimeException(e);
//                    } catch (NoSuchFieldException e) {
//                        throw new RuntimeException(e);
//                    }
                }
                //表数据发生插入时触发
            } else if (data instanceof WriteRowsEventData) {
                WriteRowsEventData writeRowsEventData = (WriteRowsEventData) data;
                long tableId1 = writeRowsEventData.getTableId();
                if(dbTableIdCols.containsKey(tableId1)){
//                    try {
//                        changeDataAutoRecord.insert(writeRowsEventData,dbTableIdCols.get(tableId1));
//                    } catch (ClassNotFoundException e) {
//                        throw new RuntimeException(e);
//                    } catch (InstantiationException e) {
//                        throw new RuntimeException(e);
//                    } catch (IllegalAccessException e) {
//                        throw new RuntimeException(e);
//                    } catch (NoSuchFieldException e) {
//                        throw new RuntimeException(e);
//                    }
                }
                //表数据发生删除后触发
            } else if (data instanceof DeleteRowsEventData) {
                DeleteRowsEventData deleteRowsEventData = (DeleteRowsEventData) data;
                long tableId1 = deleteRowsEventData.getTableId();
                if(dbTableIdCols.containsKey(tableId1)){
//                    try {
//                        changeDataAutoRecord.delete(deleteRowsEventData,dbTableIdCols.get(tableId1));
//                    } catch (ClassNotFoundException e) {
//                        throw new RuntimeException(e);
//                    } catch (InstantiationException e) {
//                        throw new RuntimeException(e);
//                    } catch (IllegalAccessException e) {
//                        throw new RuntimeException(e);
//                    } catch (NoSuchFieldException e) {
//                        throw new RuntimeException(e);
//                    }
                }
            }
        });

        try {
            client.connect();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    public static String getdbTable(String db, String table) {
        return db + "-" + table;
    }
}
